package com.start.common.transaction;

import com.start.common.interfaces.IStartApply;
import com.start.common.interfaces.IStartCallBackApply;
import com.start.common.std.StartBaseSingleton;
import com.start.common.std.StartSingletonFactory;
import com.start.common.tools.SpringContextTools;
import org.springframework.transaction.support.TransactionTemplate;


/**
 * 事务工具类型
 */
public class StartTransactionTools extends StartBaseSingleton<StartTransactionTools> {
    private static TransactionTemplate bean;

    @Override
    public void init() {
        bean = SpringContextTools.getBean(TransactionTemplate.class);
    }

    /**
     * 获取当前实例
     *
     * @return
     */
    public static StartTransactionTools getInstance() {
        return StartSingletonFactory.get(StartTransactionTools.class);
    }

    /**
     * 执行事务
     *
     * @param transaction
     */
    public void apply(IStartApply transaction) {
        Exception exception = bean.execute(status -> {
            try {
                transaction.apply();
                return null;
            } catch (Exception e) {
                status.setRollbackOnly();
                return e;
            }
        });
        if (exception != null) {
            throw new RuntimeException(exception);
        }
    }

    /**
     * 执行事务 带返回值的
     *
     * @param transactionResult
     * @param <T>
     * @return
     */

    public <T> T applyCall(IStartCallBackApply<T> transactionResult) {
        StartTransactionResult<T> execute = bean.execute(status -> {
            try {
                T apply = transactionResult.apply();
                return new StartTransactionResult<>(apply);
            } catch (Exception e) {
                status.setRollbackOnly();
                return new StartTransactionResult<>(e);
            }
        });

        assert execute != null;
        if (execute.getException() != null) {
            throw new RuntimeException(execute.getException());
        }
        return execute.getResult();
    }


}
